from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingRegressor
import joblib  # 直接导入，已经从sklearn中独立
import numpy as np


#  预测模型
class GBDTModel(object):

    def __init__(self):
        print(self.name)

    # x：       真实输入
    # y：       真实输出
    # max_bias  最大误差
    def bias_function(self, x, y, max_bias):
        bi = y
        for i in range(np.array(x).shape[0]):
            res = self.predict(x[i])
            print("预测值:%s,真实值：%s" % (res[0][0], y[i]))
            bias = y[i] - res
            bi[i] = bias[0][0]
            print("偏差:%s" % (bias[0][0]))
            if bias < 0:
                bias = -bias

            if bias > max_bias:
                max_bias = bias[0][0]
        return max_bias

    # x：      真实输入
    # y：      真实输出
    # name：   模型保存url
    # return
    def train(self, x, y, name, index):
        num_of_index = 1
        for i in range(num_of_index):
            x_train, x_test, y_train, y_test = train_test_split(x, y)
            # 模型训练，使用GBDT算法   默认75%做训练 ， 25%做测试
            '''GradientBoostingRegressor参数介绍
              @n_estimators: 子模型的数量，默认为100     200  2 2 0.1
              @max_depth   ：最大深度 ，默认3
              @min_samples_split ：分裂最小样本数
              @learning_rate ：学习率
            '''
            gbr = GradientBoostingRegressor(n_estimators=100, max_depth=3, min_samples_split=9, learning_rate=0.01)
            gbr.fit(x_train, y_train)
            joblib.dump(gbr, name + "train_model_" + str(i) + "_result.m" + str(index))  # 保存模型
            y_gbr = gbr.predict(x_train)
            y_gbr1 = gbr.predict(x_test)
            acc_train = gbr.score(x_train, y_train)
            acc_test = gbr.score(x_test, y_test)
            print(name + "train_model_" + str(i) + "_result.m" + str(index) + '训练准确率', acc_train)
            print(name + "train_model_" + str(i) + "_result.m" + str(index) + '验证准确率', acc_test)
            return acc_test

    # 加载模型并预测
    # x：      真实输入
    # name：   模型保存url
    # return   预测值
    def predict(self, x, name, index):
        x_pred = x
        x_pred = np.reshape(x_pred, (1, -1))
        num_of_index = 1
        for i in range(num_of_index):
            gbr = joblib.load(name + "train_model_" + str(i) + "_result.m" + str(index))  # 加载模型
            test_y = gbr.predict(x_pred)
        test_y = np.reshape(test_y, (1, -1))
        # print(test_y)
        return test_y
